import type { UserConfigExport, ConfigEnv } from 'vite'

import { loadEnv } from 'vite'
import { resolve } from 'path'
import dayjs from 'dayjs'

import { wrapperEnv } from './build/utils'
import { createVitePlugins } from './build/vite/plugin'
import { createProxy } from './build/vite/proxy'
import pkg from './package.json'

// 从 package.json 获取信息，并组合
const { name, version, dependencies, devDependencies } = pkg
const __APP_INFO__ = {
  pkg: { name, version, dependencies, devDependencies },
  lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
}

// 处理路径
// process.cwd() 是当前执行 node 命令时候的文件夹地址 —— 工作目录
function pathResolve(dir: string) {
  return resolve(process.cwd(), '.', dir)
}

export default ({ command, mode }: ConfigEnv): UserConfigExport => {
  const root = process.cwd()
  const env = loadEnv(mode, root)
  const viteEnv = wrapperEnv(env)
  const { VITE_PORT, VITE_PROXY } = viteEnv
  const isBuild = command === 'build'

  return {
    resolve: {
      // 相对路径的别名值
      alias: [
        {
          find: '/#/',
          replacement: pathResolve('types') + '/',
        },
        {
          find: '@/',
          replacement: pathResolve('src') + '/',
        },
      ],
      // 如果你在你的应用程序中有相同依赖的副本（比如 monorepos），请使用此选项强制 Vite 始终将列出的依赖项解析为同一副本（从项目根目录）
      dedupe: ['vue'],
    },
    // 插件
    plugins: createVitePlugins(viteEnv, isBuild),
    // 定义全局常量替换方式。其中每项在开发环境下会被定义在全局，而在构建时被静态替换。
    define: {
      __APP_INFO__: JSON.stringify(__APP_INFO__),
    },
    server: {
      // 指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址，包括局域网和公网地址
      host: true,
      // 指定开发服务器端口。注意：如果端口已经被使用，Vite 会自动尝试下一个可用的端口，所以这可能不是开发服务器最终监听的实际端口。
      port: VITE_PORT,
      // 在开发服务器启动时自动在浏览器中打开应用程序
      open: '/',
      // 为开发服务器配置自定义代理规则
      proxy: createProxy(VITE_PROXY),
      // proxy: {
      //     '/api': {
      //         target: 'http://jsonplaceholder.typicode.com',
      //         changeOrigin: true,
      //         rewrite: (path) => path.replace(/^\/api/, '/api/v1')
      //     }
      // }
    },
    build: {
      // chunk 大小警告的限制（以 kbs 为单位）。
      chunkSizeWarningLimit: 2000,
    },
  }
}
